﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data;
using Npgsql;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;

namespace SpectationClient.Async {
    public delegate void ProgressChangedEventHandler(object sender, ProgressChangedEventArgs e);
    
    public abstract class ABase {
        public event ProgressChangedEventHandler ProgressChanged;
        protected delegate void WorkerEventHandler(NpgsqlCommand cmd, AsyncOperation asyncOp);

        protected virtual void InitializeDelegates() {
            onProgressChangedDelegate = new SendOrPostCallback(ReportProgress);
        }

        protected HybridDictionary userStateToLifetime = new HybridDictionary();
        public Int32 ActiveRequests { get { return userStateToLifetime.Count; } }
        
        protected SendOrPostCallback onProgressChangedDelegate;
     
        /// <summary>
        /// This method cancels a pending asynchronous operation. 
        /// Overwrite to return a meaningful PostOperationCompleted result
        /// </summary>
        /// <param name="taskId"></param>
        public void CancelAsync(object taskId) {
            AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
            if(asyncOp != null) {
                lock(userStateToLifetime.SyncRoot) {
                    userStateToLifetime.Remove(taskId);
                }
                
                OnCancelAsync(asyncOp);
            }
        }

        /// <summary>
        /// This method is called in case of a cancelation.
        /// Use it to call e.g. onGetDataTableCompletedDelegate with GetDataTableCompletedEventArgs
        /// </summary>
        protected abstract void OnCancelAsync(AsyncOperation asyncOp);

        public void CancelAllRequest() {
            foreach(object taskID in userStateToLifetime.Values) {
                CancelAsync(taskID);
            }
        }

        // This method is invoked via the AsyncOperation object,
        // so it is guaranteed to be executed on the correct thread.
        protected void ReportProgress(object state) {
            ProgressChangedEventArgs e = state as ProgressChangedEventArgs;
            OnProgressChanged(e);
        }

        protected void OnProgressChanged(ProgressChangedEventArgs e) {
            if(ProgressChanged != null) ProgressChanged(this, e);
        }

        // Utility method for determining if a 
        // task has been canceled.
        protected bool TaskCanceled(object taskId) {
            return (userStateToLifetime[taskId] == null);
        }


    }
}
